<?php
/**
 * @see Zend_Db_Table_Abstract
 */
require_once 'Zend/Db/Table.php';

/**
 * Classe abstract de controle de acesso ao BD
 * @author Cristiano Teles <cristianoteles@estradavirtual.com.br>
 *
 */
abstract class Ev_Db_Table extends Zend_Db_Table
{
    const K_INSERT = 1;
    const K_UPDATE = 2;
    protected $_descricao;
    protected $_stMensagem = null;

    /**
     * Gravação de dados na tabela
     * @param $aDados array
     * @return id
     */
    public function gravar(array $aDados)
    {
        $sId = $this->getPrimaryKeyName();

        if (empty($aDados[$sId])) {
            unset( $aDados[$sId] );
            $oRow = $this->createRow();
            $mode = Ev_Db_Table::K_INSERT;
        } else {
            $oRow = $this->find( $aDados[$sId] )->current();
            $mode = Ev_Db_Table::K_UPDATE;
        }
        //Limpa dados vazios
        $aDadosGravar = array();
        foreach ($aDados as $coluna => $valor) {
            if($valor === '') continue;
            $aDadosGravar[$coluna] = $valor;
        }
        $oRow->setFromArray($aDadosGravar);
        $oRow = $this->_preSave($oRow, $mode);
        return $oRow->save();
    }

    /**
     * Método chamado antes da salvar o registro, utilizado para validações de table
     * @param $oRow Zend_Db_Table_Row
     * @return unknown_type
     */
    public function _preSave($oRow, $mode)
    {
        $aInfo   = $this->info();
        $aCampos = $aInfo['metadata'];
        unset($aInfo);

        foreach ($aCampos as $sCampo => $aInfo) {
            if (substr( $aInfo["DATA_TYPE"], 0, 4 ) == 'date') {
                if (!empty($oRow->$sCampo)) {
                    $obData = new Zend_Date($oRow->$sCampo, 'pt_BR');
                    $oRow->$sCampo = $aInfo["DATA_TYPE"] == 'date' ? $obData->get('YYYY-MM-dd') : $obData->get('YYYY-MM-dd HH:m:ss');
                    unset($obData);
                }
            }
        }

        if ($mode == Ev_Db_Table::K_INSERT) {
            if (isset($oRow->datacadastro)) {
                $oRow->datacadastro = date( 'Y-m-d' );
            }
            if (isset($oRow->dt_cadastro)) {
                $oRow->dt_cadastro = date( 'Y-m-d H:i:s' );
            }
        }
        return $oRow;
    }

    /**
     * Retorna o nome da chave primária da tabela
     * @return string
     */
    public function getPrimaryKeyName()
    {
        $aInfoModelo = $this->info();
        return $aInfoModelo['primary'][1];
    }

    /**
     * Retornar array de registros de tabelas associadas
     * @return array
     */
    public function carregarArrayDadosReference()
    {
        $aRefMaps = $this->_getReferenceMapNormalized();

        $aReturn = array();
        foreach ($aRefMaps as $sRef => $aRef) {
            $oModel = new $aRef['refTableClass'];
            $aReturn[$aRef['columns'][0]] = $oModel->getArrayAssociative();
        }
        return $aReturn;
    }

    /**
     * Retornar array de registros da tabela, utlizando a pk como indice
     * @param $sDescription Descrição que será colocar como value do array
     * @param $where Filtro de registros
     * @param $order string|array Campos para ordenar
     * @param $count
     * @param $aMerge
     * @return array
     */
    public function getArrayAssociative( $sDescription = null, $where = null, $order = null, $count = null, $aMerge = array( '' => 'Selecione') )
    {
        $oRowSet = $this->fetchAll($where, $order, $count);
        $sKey    = $this->getPrimaryKeyName();

        if (empty($sDescription)) {
            $sDescription = $this->_descricao;
        }

        $aReturn = $aMerge;
        while ($oRow = $oRowSet->current()) {
            if (empty($sDescription)) {
                switch (true) {
                    case isset($oRow->st_nome)      : $sDescription = 'st_nome';      break;
                    case isset($oRow->st_descricao) : $sDescription = 'st_descricao'; break;
                }
            }
            $aReturn[$oRow->$sKey] = $oRow->$sDescription;
            $oRowSet->next();
        }
        return $aReturn;
    }

    /**
     * Retorna a Row de uma tabela por id
     * @param int $id - Identificador da Tabela
     * @return array - Row da tabela
     */
    public function getRowPorId($id = null)
    {
         if ($id) {
            $row = $this->find($id)->current();
            if ($row){
                return $row->toArray();
            }
        }
        return $this->createRow()->toArray();
    }

    /**
     * Tenta descobrir qual o campo de descrição da tabela
     * @return string Nome do campo de descrição da tabela
     */
    public function getCampoDescricao()
    {
        $aInfo = $this->info();

        foreach($aInfo['cols'] as $sCampo) {
            switch ($sCampo) {
                case 'nome'         : return 'nome';
                case 'st_nome'      : return 'st_nome';
                case 'st_descricao' : return 'st_descricao';
            }
        }
        return '';
    }
    
	/**
     * Método chamado antes da excluir o registro
     * @param int - Identificador do registro a ser excluído
     * @return bool
     */
    protected function _preExcluir($id)
    {
        return true;
    }

    public function excluir($id)
    {
        if (!$this->_preExcluir($id)){
            return false;
        }
        if($row = $this->find($id)->current()) {
            return $row->delete();
        }
        return false;
    }
    
    public function getMessage()
    {
        return $this->_stMensagem;   	
    }
}
